package com.beici.waterghost.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.beici.waterghost.except.selectError;
import com.beici.waterghost.model.login.userLogin;
import com.beici.waterghost.model.resultes;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

import java.net.PasswordAuthentication;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

@Service
public class loginService {

    @Autowired
    private AuthenticationManager authenticationManagerBean;

    @Autowired
    private StringRedisTemplate redisTemplate;

    public resultes login(String email,String key){
        // 唤起登录
        Authentication authentication = null;
        try {
            authentication =  authenticationManagerBean.authenticate(new UsernamePasswordAuthenticationToken(email,key));
        }catch (Exception e){
            // 登录失败 那么就记录用户登录次数
             if( addUserLoginErrorCount(Long.valueOf(email)) ){
               return resultes.divResultes(null, "密码错误", 2001);
            }
            if (e instanceof selectError){
                return resultes.error("账号不存在");
            }else if(e instanceof BadCredentialsException){
                return resultes.error("密码尚未经过加密 请联系管理员");
            }else {
                e.printStackTrace();
                return resultes.error("账号已被冻结");
            }
        }
        // 登录成功后 我们要取出他的主体绑定TOKEN
        UUID uuid = UUID.randomUUID();
        // 获取主题
        userLogin principal = (userLogin) authentication.getPrincipal();
        // 进行绑定
        boolean b = bindUser(uuid, String.valueOf(principal.getUserId()));
        return b?resultes.success("登录成功",uuid.toString()):resultes.error("登录失败");

    }

    public resultes miniAppLogin(String openId){
        // 唤起登录
        Authentication authentication = null;
        try {
            authentication =  authenticationManagerBean.authenticate(new UsernamePasswordAuthenticationToken(openId,"mini"));
        }catch (Exception e){
            if (e instanceof selectError){
                return resultes.error("账号不存在");
            }else if(e instanceof BadCredentialsException){
                return resultes.error("密码尚未经过加密 请联系管理员");
            }else {
                e.printStackTrace();
                return resultes.error("账号已被冻结");
            }
        }
        // 登录成功后 我们要取出他的主体绑定TOKEN
        UUID uuid = UUID.randomUUID();
        // 获取主题
        userLogin principal = (userLogin) authentication.getPrincipal();
        // 进行绑定
        boolean b = bindUser(uuid, String.valueOf(principal.getUserId()));
        return b?resultes.success("登录成功",uuid.toString()):resultes.error("登录失败");

    }

    /**
     * 记录用户登录错误次数 一旦大于3转验证码
     * @param phone
     */
    private boolean addUserLoginErrorCount(Long phone){
        Integer s=0;
        try {
             s = Integer.valueOf(redisTemplate.opsForValue().get(phone + "logincode"));
        }catch (NumberFormatException e){
            redisTemplate.opsForValue().set(phone+"logincode","0");
        }
        if (s>=3){
            return true;
        }
        redisTemplate.opsForValue().set(phone+"logincode", String.valueOf(++s),1,TimeUnit.DAYS);
        return false;
    }

    private boolean bindUser(UUID uuid,String userId) {
        // 将用户转成JSON
        redisTemplate.opsForValue().set(uuid.toString(),userId,1, TimeUnit.HOURS);
        return true;
    }

}
